package org.jeecg.activiti.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.jeecg.activiti.service.IActUserService;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysPosition;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysPositionService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.weixin.cp.api.WxCpMessageService;
import org.jeecg.weixin.cp.api.WxCpService;
import org.jeecg.weixin.cp.api.impl.WxCpMessageServiceImpl;
import org.jeecg.weixin.cp.bean.message.WxCpMessage;
import org.jeecg.weixin.web.config.WxCpConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

@Service(value = "actUserService")
public class ActUserServiceImpl implements IActUserService {
	
	@Value("${jeecg.wx.bpmn.agentId}")
	private Integer agentId;
	
	@Autowired
	private ISysUserDepartService iSysUserDepartService;
	
	@Autowired
	private ISysUserService iSysUserService;
	
	@Autowired
	private ISysDepartService iSysDepartService;
	
	@Autowired
	private ISysPositionService iSysPositionService;
	
	@Autowired
	private ISysBaseAPI iSysBaseAPI;

	@Override
	public String getDepartLeaders(String username, String positionRank) {
		SysUser user = iSysUserService.getUserByName(username);
		List<SysDepart> depts = iSysDepartService.queryUserDeparts(user.getId());
		List<SysUser> leaders = new ArrayList<>();
		for(SysDepart dept : depts){
			leaders.addAll(getLeadersByDepartId(dept, positionRank));
		}
		StringBuffer result = new StringBuffer();
		for(SysUser leader : leaders){
			result.append(leader.getUsername()+",");
		}
		if(result.length()>0){
			result.setLength(result.length() - 1);
		}
		return result.toString();
	}
	
	private List<SysUser> getLeadersByDepartId(SysDepart sysDept, String positionRank){
		boolean hasParentDept = true;
		List<SysUser> result = new ArrayList<>();
		List<SysUser> users = iSysUserDepartService.queryUserByDepId(sysDept.getId());
		
		for(SysUser user : users){
			if(user.getStatus() == 2){
				continue;
			}
			String postCode = user.getPost();
			int count = iSysPositionService.count(new QueryWrapper<SysPosition>().eq("code", postCode).eq("post_rank", positionRank));
			if(count>0){
				result.add(user);
			}
		}
		String parentId = sysDept.getParentId();
		while(hasParentDept && result.size() == 0){
			SysDepart dept = iSysDepartService.getById(parentId);
			if(dept == null){
				hasParentDept = false;
			}else{
				List<SysUser> deptUsers = iSysUserDepartService.queryUserByDepId(dept.getId());
				for(SysUser user : deptUsers){
					if(user.getStatus() == 2){
						continue;
					}
					String postCode = user.getPost();
					int count = iSysPositionService.count(new QueryWrapper<SysPosition>().eq("code", postCode).eq("post_rank", positionRank));
					if(count>0){
						result.add(user);
					}
				}
				if(result.size() == 0){
					parentId = dept.getParentId();
				}
			}
		}
		return result;
	}

	@Override
	public boolean checkPositionRank(String username, String positionRank) {
		boolean result = false;
		SysUser user = iSysUserService.getUserByName(username);
		if(user != null && user.getPost() != null){
			List<SysPosition> posts = iSysPositionService.list(new QueryWrapper<SysPosition>().eq("code", user.getPost()));
			for(SysPosition post : posts){
				if(positionRank.equals(post.getPostRank())){
					result = true;
					break;
				}
			}
		}
		return result;
	}
	
	@Override
	public boolean checkDept(String username, String deptCode) {
		SysDepart dept = iSysDepartService.getOne(new QueryWrapper<SysDepart>().eq("org_code", deptCode));
		SysUser user = iSysUserService.getUserByName(username);
		
		return checkDepts(user.getOrgCode(), new ArrayList<SysDepart>(Arrays.asList(dept)));
	}

	private boolean checkDepts(String deptCodes, List<SysDepart> depts) {
		if(!StringUtils.hasText(deptCodes)){
			return false;
		}
		String[] deptCodeArr = deptCodes.split(",");
		for(SysDepart depart : depts){
			for(String deptCode : deptCodeArr){
				if(deptCode.equals(depart.getOrgCode())){
					return true;
				}
			}
			List<SysDepart> subDepts = iSysDepartService.list(new QueryWrapper<SysDepart>().eq("parent_id", depart.getId()));
			if(!CollectionUtils.isEmpty(subDepts)){
				if(checkDepts(deptCodes, subDepts)){
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public void sendMessage(String fromUser, String toUser, String title, String content) {
		try{
			MessageDTO msg = new MessageDTO();
            msg.setFromUser(fromUser);
            msg.setToUser(toUser);
            msg.setTitle(title);
            msg.setContent(content);
            msg.setCategory("2");
            iSysBaseAPI.sendSysAnnouncement(msg);
			
			WxCpService wxCpService =  WxCpConfiguration.getCpService(agentId);
    		WxCpMessageService wxCpMessageService = new WxCpMessageServiceImpl(wxCpService);
    		String[] users = toUser.split(",");
    		List<String> wxUsernames = new ArrayList<>();
    		for(String username : users){
    			LoginUser _user = iSysBaseAPI.getUserByName(username);
    			if(_user != null){
    				wxUsernames.add(_user.getThirdId());
    			}
    		}
    		String wxUser = String.join("|", wxUsernames);
    		WxCpMessage message = WxCpMessage.TEXT().toUser(wxUser).agentId(wxCpService.getWxCpConfigStorage().getAgentId()).content(content).build();
    		wxCpMessageService.send(message);
        }catch (Exception e) {
		}
	}

	@Override
	public String getDepartLeadersByDept(String deptCode, String positionRank) {
		SysDepart dept = iSysDepartService.getOne(new QueryWrapper<SysDepart>().eq("org_code", deptCode));
		if(dept == null){
			return null;
		}else{
			List<SysUser> users = getLeadersByDepartId(dept, positionRank);
			if(CollectionUtils.isEmpty(users)|| users.size() != 1){
				return null;
			}else{
				return users.get(0).getUsername();
			}
		}
	}
}
